/**
 * @author Johann Prieur
 */
package mygui;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

import utils.*;
import kernel.*;
import objects.*;

public class SensorNetworkProperties extends Properties {

    private Simulator _kernel;
    private SensorNetwork _sensor_network;
    private DataSensorNetwork _data;
    private DataSensor _data_sensor;

    private JTabbedPane _tabs;

    private GeneralPanel _general;
    private SensorPanel _sensor;
    private EmissionPanel _emissions;

    public SensorNetworkProperties(SensorNetwork network)
    {
	setTitle("Sensor type properties");
	_sensor_network = network;
	_data = (DataSensorNetwork)_sensor_network.getProperties();
	_data_sensor = _data.getDataSensor();
	_kernel = Simulator.getSimulator();
 	_tabs = new JTabbedPane(JTabbedPane.TOP,
 				JTabbedPane.SCROLL_TAB_LAYOUT);

	_general = new GeneralPanel();
	_sensor = new SensorPanel();
	_emissions = new EmissionPanel();

	_tabs.add(_general, "General");
	_tabs.add(_sensor, "Sensors");
	//_tabs.add(_emissions, "Emissions");

	add("North", new ObjectIdCard(Type.wireless,
				      _data.getName(),
				      "Sensor network"));
	add("Center", _tabs);
	pack();
	WindowUtilities.centerFrame(this);
	setVisible(true);
    }

    public void apply()
    {
	_general.apply();
	
	_sensor.apply();
	_emissions.apply();
	_sensor_network.setProperties(_data);
	SensorSimulator kernel = (SensorSimulator)_kernel;
	// If this is the first time the sensor network is configured (ie when created)
	// then we add it to the kernel
	if(!kernel.getSensorNetworkVector().contains(_sensor_network))
	    kernel.addSensorNetwork(_sensor_network);

	/*	if(_general.getMakeModelSelected()){
	    ModelManager.getModelManager().addModel(_general.getModelName(),_data);
	}
	*/
    }

    private class GeneralPanel extends JPanel  implements ActionListener 
    {
	private JTextField _name;
	private String _name_tip = "Name of the sensor network";

	private JButton _color;

	private JSpinner _x;
	private String _x_tip = "x coordinate of the sensor network";

	private JSpinner _y;
	private String _y_tip = "y coordinate of the sensor network";

	private JSpinner _width;
	private String _width_tip = "width of the sensor network";

	private JSpinner _height;
	private String _height_tip = "height of the sensor network";

	private JSpinner _number;
	private String _number_tip = "Number of sensor";

	private JComboBox _repartition;
	private String _repartition_tip = "Distribution type";

	private JSpinner _k_cover;
	private String _k_cover_tip = "K-cover";

	private JComboBox _sleep;
	private String _sleep_tip = "Sleeping mode";

	private JSpinner _sleep_loop;
	private String _sleep_loop_tip = "Sleeping loop period";

	private JCheckBox _make_model;
	private String _make_model_tip = "Convert into model";
	
	private JTextField _model_name;
	private String _model_name_tip = "Model name";

	private JComboBox _probesBox;

	private JButton _add;
	private JButton _remove;
	private DefaultListModel _model;
	private JList _list;
	

	private GeneralPanel()
	{
	    setLayout(new BorderLayout());
	    
	    JPanel general = new JPanel();
	    JPanel probes = new JPanel(new BorderLayout());
	    JPanel probes_buttons = new JPanel();
	    probes_buttons.setLayout(new GridLayout(2,2,4,4));
	    
	    JPanel model = new JPanel();
	    model.setLayout(new GridLayout(1,2,4,4));

	    general.setLayout(new GridLayout(11,2,4,4));
	    general.setBorder(new EmptyBorder(4,4,4,4));
	    
	    _name = new JTextField(_data.getName());
	    _color = new JButton("pick a color...");
	    _color.setForeground(_data.getColor());
	    _color.addActionListener(this);

	    _x = new JSpinner(new SpinnerNumberModel(_data.getCoordX(),
						     DataSensorNetwork.COORD_X_MIN,
						     Simulator.getSimulator().getEnvironment().getSpace().getWidth(),
						     1));
	    _x.setToolTipText(_x_tip);
	    _y = new JSpinner(new SpinnerNumberModel(_data.getCoordY(),
						     DataSensorNetwork.COORD_Y_MIN,
						     Simulator.getSimulator().getEnvironment().getSpace().getHeight(),
						     1));
	    _width = new JSpinner(new SpinnerNumberModel(_data.getWidth(),
							 DataSensorNetwork.WIDTH_MIN,
							 _kernel.getEnvironment().getSpace().getWidth(),
							 1));
	    _height = new JSpinner(new SpinnerNumberModel(_data.getHeight(),
							  DataSensorNetwork.HEIGHT_MIN,
							  _kernel.getEnvironment().getSpace().getHeight(),
							  1));
	    _number = new JSpinner(new SpinnerNumberModel(_data.getAmount(),
							  DataSensorNetwork.AMOUNT_MIN,
							  DataSensorNetwork.AMOUNT_MAX,
							  1));
	    _sleep_loop = new JSpinner(new SpinnerNumberModel(_data.getSleepingPeriod(),
							  DataSensorNetwork.SLP_PERIOD_MIN,
							  DataSensorNetwork.SLP_PERIOD_MAX,
							  1));
	    
	    StrategyChoser sc = new StrategyChoser("objects.distribution");
	    sc.checkSuperclass("DistributionAlgo");
	    Vector<Class> strats = sc.getStrategies();
	    Vector<String> strat_labels = new Vector();
	    for(Class strat : strats){
		String[] path = strat.toString().split("[.]");
		strat_labels.add(path[path.length-1]);
	    }
	    _repartition = new JComboBox(strat_labels);
	    Class distribution = _data.getDistributionAlgo().getClass();
	    String[] path2 = distribution.toString().split("[.]");
	    _repartition.setSelectedItem(path2[path2.length-1]);

	    StrategyChoser sc2 = new StrategyChoser("sleeping");
	    sc2.checkSuperclass("SleepingAlgo");
	    Vector<Class> strats2 = sc2.getStrategies();
	    Vector<String> strat_labels2 = new Vector();
	    for(Class strat : strats2){
		String[] path = strat.toString().split("[.]");
		strat_labels2.add(path[path.length-1]);
	    }
	    _sleep = new JComboBox(strat_labels2);
	    Class sleeping = _data.getSleepingAlgo().getClass();
	    String[] path = sleeping.toString().split("[.]");
	    _sleep.setSelectedItem(path[path.length-1]);

	    _k_cover = new JSpinner(new SpinnerNumberModel(_data.getKCover(),
							   DataSensorNetwork.K_MIN,
							   DataSensorNetwork.K_MAX,
							   1));
	    _make_model = new JCheckBox(_make_model_tip,false);
	    _make_model.addActionListener(this);

	    _model_name = new JTextField("");

	    Vector<String> strat_labels3 = new Vector();

	    StrategyChoser scSensorNetwork = new StrategyChoser("results");
	    scSensorNetwork.checkSuperclass("ProbeSensorNetwork");
	    Vector<Class> stratsSensorNetwork = scSensorNetwork.getStrategies();

	    for(Class strat : stratsSensorNetwork){
		String[] path3 = strat.toString().split("[.]");
		strat_labels3.add(path3[path3.length-1]);
	    }
	    _probesBox = new JComboBox(strat_labels3);

	    _add = new JButton(UIM.createImageIcon("images/add.png",""));
	    _add.addActionListener(this);
	    _remove = new JButton(UIM.createImageIcon("images/remove.png",""));
	    _remove.addActionListener(this);
	    _model = new DefaultListModel();
	    _list = new JList(_model);

	    //System.out.println(_data.getProbes().size()); //->
	    for(Object probe: _data.getProbes())
		_model.addElement(probe);

	    general.add(new JLabel("Name"));
	    general.add(_name);
	    general.add(new JLabel("Color"));
	    general.add(_color);
	    general.add(new JLabel("x coordinate"));
	    general.add(_x);
	    general.add(new JLabel("y coordinate"));
	    general.add(_y);
	    general.add(new JLabel("Width"));
	    general.add(_width);
	    general.add(new JLabel("Height"));
	    general.add(_height);
	    general.add(new JLabel("Amount of sensors"));
	    general.add(_number);
	    general.add(new JLabel("Distribution type"));
	    general.add(_repartition);
	    general.add(new JLabel("K-cover"));
	    general.add(_k_cover);
	    general.add(new JLabel("Sleeping mode"));
	    general.add(_sleep);
	    general.add(new JLabel("Sleeping loop period"));
	    general.add(_sleep_loop);

	    probes_buttons.add(new JLabel("Probes"));
	    probes_buttons.add(_probesBox);
	    probes_buttons.add(_add);
	    probes_buttons.add(_remove);
	    probes.add("North",probes_buttons);
	    probes.add("Center",new JScrollPane(_list));

	    //model.add(_make_model);
	    //model.add(_model_name);
	    //_model_name.setToolTipText(_model_name_tip);
	    //_model_name.setEnabled(false);

	    add("North",general);
	    add("Center",probes);
	    //add("South",model);
	}

	public boolean getMakeModelSelected(){
	    return _make_model.isSelected();
	}

	public String getModelName(){
	    return _model_name.getText();
	}

	public void actionPerformed(ActionEvent e)
	{
	    Component source = (Component)e.getSource();
	    if(source == _color)
		{
		    Color color = JColorChooser.showDialog(this,
							    "Choose the sensor network color",
							    _color.getForeground());
		    if(color != null) _color.setForeground(color);
		}
	    if(source == _add)
		{
		    _model.addElement((String)_probesBox.getSelectedItem());
		}
	    else if(source == _remove)
		{
		    int index = _list.getSelectedIndex();
		    if(index != -1) _model.remove(index);
		}
	    else if(source == _make_model)
		{
		    _model_name.setEnabled(_make_model.isSelected());
		}
	}

	public void apply()
	{
	    _data.setName(_name.getText());
	    _data.setColor(_color.getForeground());
	    _data.setCoordX(((Double)_x.getValue()).doubleValue());
	    _data.setCoordY(((Double)_y.getValue()).doubleValue());
	    _data.setWidth(((Double)_width.getValue()).doubleValue());
	    _data.setHeight(((Double)_height.getValue()).doubleValue());
	    _data.setAmount(((Integer)_number.getValue()).intValue());
	    _data.setKCover(((Integer)_k_cover.getValue()).intValue());
	    _data.setDistributionAlgo((String)_repartition.getSelectedItem());
	    _data.setSleepingAlgo((String)_sleep.getSelectedItem());
	    _data.setSleepingPeriod(((Integer)_sleep_loop.getValue()).intValue());
	    _data.setKCover(((Integer)_k_cover.getValue()).intValue());

	    Vector probes = new Vector();
	    for(Enumeration e = _model.elements() ; e.hasMoreElements() ;) {
		probes.add(e.nextElement());
	    }
	    _data.setProbes(probes);
	    
	}
    }

    private class SensorPanel extends JPanel implements ActionListener{

	private JSpinner _measRad;
	
        private JTextField _name;
	private String _name_tip = "Name of the base station";

	private JSpinner _max_reach_length;
	private String _max_reach_length_tip = "Wave length in meters";

	private JSpinner _carrier_rate;
	private String _carrier_rate_tip = "Carrier rate.\n" +
	    "Must be upper or equal to 1.0";

	private JSpinner _max_frequency;
	private String _max_frequency_tip = "Maximum communication frequency";

	private JSpinner _min_frequency;
	private String _min_frequency_tip = "Minimum communication frequency";

	private JSpinner _nb_frequency;
	private String _nb_frequency_tip = "Number of communication frequencies";

	private JTextField _model_name;
	private String _model_name_tip = "Model name";

	//private JComboBox _probes;

	/*	private JButton _add;
	private JButton _remove;
	private DefaultListModel _model;
	private JList _list;*/

	private JSpinner _battery;
	private JSpinner _waiting;
	private JSpinner _speaking;
	private JSpinner _listening;
	private JSpinner _sleeping;
	private JComboBox _controllerStrategy;

	private SensorPanel()
	{
	    setLayout(new BorderLayout());
	    
	    JPanel sensor = new JPanel();	    
	    sensor.setLayout(new GridLayout(12,2,4,4));
	    sensor.setBorder(new EmptyBorder(4,4,4,4));
	 
	    /*JPanel probes = new JPanel(new BorderLayout());
	    JPanel probes_buttons = new JPanel();
	    probes_buttons.setLayout(new GridLayout(2,2,4,4));*/
	 	    
	    _measRad = new JSpinner(new SpinnerNumberModel(_data_sensor.getMeasurementRadius(),
						     DataSensor.MEAS_RAD_MIN,
						     DataSensor.MEAS_RAD_MAX,
						     1));

	    /*Vector<String> strat_labels = new Vector();
	    StrategyChoser scEnergy = new StrategyChoser("results");
	    scEnergy.checkSuperclass("ProbeEnergy");
	    Vector<Class> stratsEnergy = scEnergy.getStrategies();

	    StrategyChoser scCom = new StrategyChoser("results");
	    scCom.checkSuperclass("ProbeCom");
	    Vector<Class> stratsCom = scCom.getStrategies();

	    for(Class strat : stratsEnergy){
		String[] path = strat.toString().split("[.]");
		strat_labels.add(path[path.length-1]);
	    }
	    for(Class strat : stratsCom){
		String[] path = strat.toString().split("[.]");
		strat_labels.add(path[path.length-1]);
		}*/
	    
	    // _probes = new JComboBox(strat_labels);
	     
	    _carrier_rate = new JSpinner(new SpinnerNumberModel());

	    double max = Math.max(Simulator.getSimulator().getEnvironment().getSpace().getWidth(),
			   Simulator.getSimulator().getEnvironment().getSpace().getHeight());

	    _max_reach_length = new JSpinner(new SpinnerNumberModel(_data_sensor.getMaxReachRadius(),
 								    DataMobileStation.MAX_REACH_RADIUS_MIN,
 								    max, 1));
 	    _carrier_rate = new JSpinner(new SpinnerNumberModel(_data_sensor.getCarrierRate(),
								DataMobileStation.CARRIER_RATE_MIN,
								max, 1));

	    _min_frequency = new JSpinner(new SpinnerNumberModel(_data_sensor.getFmin(),
								 DataMobileStation.FMIN_MIN,
								 DataMobileStation.FMIN_MAX,
								 1));
	    _max_frequency = new JSpinner(new SpinnerNumberModel(_data_sensor.getFmax(),
								 DataMobileStation.FMAX_MIN,
								 DataMobileStation.FMAX_MAX,
								 1));
	    _nb_frequency = new JSpinner(new SpinnerNumberModel(_data_sensor.getNbFreq(),
								 DataMobileStation.FNB_MIN,
								 DataMobileStation.FNB_MAX,
								1));

	    /* _add = new JButton(UIM.createImageIcon("images/add.png",""));
	    _add.addActionListener(this);
	    _remove = new JButton(UIM.createImageIcon("images/remove.png",""));
	    _remove.addActionListener(this);
	    _model = new DefaultListModel();
	    _list = new JList(_model);
	    for(Object probe: _data_sensor.getProbes())
	    _model.addElement(probe);*/


	    _battery = new JSpinner(new SpinnerNumberModel(_data_sensor.getBatteryLevel(),
							   DataMobileStation.BATTERY_LEVEL_MIN,
							   DataMobileStation.BATTERY_LEVEL_MAX,
							   1));
	    double[] consumptions = _data_sensor.getConsumption();
	    _waiting = new JSpinner(new SpinnerNumberModel(consumptions[Station.WAITING],
							   DataMobileStation.CONSUMPTION_MIN[Station.WAITING],// *3600000
							   DataMobileStation.CONSUMPTION_MAX[Station.WAITING],
							   1));
	    _speaking = new JSpinner(new SpinnerNumberModel(consumptions[Station.SPEAKING],
							   DataMobileStation.CONSUMPTION_MIN[Station.SPEAKING],// *3600000
							   DataMobileStation.CONSUMPTION_MAX[Station.SPEAKING],
							   1));
	    _listening = new JSpinner(new SpinnerNumberModel(consumptions[Station.LISTENING],
							   DataMobileStation.CONSUMPTION_MIN[Station.LISTENING],// *3600000
							   DataMobileStation.CONSUMPTION_MAX[Station.LISTENING],
							   1));
	    _sleeping = new JSpinner(new SpinnerNumberModel(consumptions[Station.SLEEPING],
							   DataMobileStation.CONSUMPTION_MIN[Station.SLEEPING],// *3600000
							   DataMobileStation.CONSUMPTION_MAX[Station.SLEEPING],
							   1));
	    StrategyChoser sc2 = new StrategyChoser("comRadiusController");
	    sc2.checkSuperclass("ComRadiusController");
	    Vector<Class> strats2 = sc2.getStrategies();
	    Vector<String> strat_labels2 = new Vector();
	    for(Class strat : strats2){
		String[] path = strat.toString().split("[.]");
		strat_labels2.add(path[path.length-1]);
	    }
	    _controllerStrategy = new JComboBox(strat_labels2);
	    Class controller = _data_sensor.getController().getClass();
	    String[] path = controller.toString().split("[.]");
	    _controllerStrategy.setSelectedItem(path[path.length-1]);

	    
	    sensor.add(new JLabel("Measurement Radius"));
	    sensor.add(_measRad);

	    sensor.add(new JLabel("Max reachable radius"));
	    sensor.add(_max_reach_length);
	    _max_reach_length.setToolTipText(_max_reach_length_tip);

	    sensor.add(new JLabel("Carrier rate"));
	    sensor.add(_carrier_rate);		
	    _carrier_rate.setToolTipText(_carrier_rate_tip);

	    sensor.add(new JLabel("Min communication frequency"));
	    sensor.add(_min_frequency);
	    _min_frequency.setToolTipText(_min_frequency_tip);

	    sensor.add(new JLabel("Max communication frequency"));
	    sensor.add(_max_frequency);
	    _max_frequency.setToolTipText(_max_frequency_tip);

	    sensor.add(new JLabel("Number of communication frequencies"));
	    sensor.add(_nb_frequency);
	    _nb_frequency.setToolTipText(_min_frequency_tip);

	    sensor.add(new JLabel("Initial battery level (%)"));
	    sensor.add(_battery);

	    sensor.add(new JLabel("Watching consumption (% per hour)"));
	    sensor.add(_waiting);

	    sensor.add(new JLabel("Listening consumption (% per hour)"));
	    sensor.add(_listening);

	    sensor.add(new JLabel("Transmitting consumption (% per hour)"));
	    sensor.add(_speaking);

	    sensor.add(new JLabel("Sleeping consumption (% per hour)"));
	    sensor.add(_sleeping);

	    sensor.add(new JLabel("Communication radius controller"));
	    sensor.add(_controllerStrategy);


	    /*probes_buttons.add(new JLabel("Probes"));
	    probes_buttons.add(_probes);
	    probes_buttons.add(_add);
	    probes_buttons.add(_remove);
	    probes.add("North",probes_buttons);
	    probes.add("Center",new JScrollPane(_list));*/

	    add("North", sensor);
	    //add("Center",probes);
	}

	public void apply()
	{
	    _data_sensor.setMaxReachRadius(((Double)_max_reach_length.getValue()).doubleValue());
	    _data_sensor.setCarrierRate(((Double)_carrier_rate.getValue()).doubleValue());
	    _data_sensor.setFmin(((Double)_min_frequency.getValue()).floatValue());
	    _data_sensor.setFmax(((Double)_max_frequency.getValue()).floatValue());
	    _data_sensor.setNbFreq(((Integer)_nb_frequency.getValue()).intValue());
	    _data_sensor.setMeasurementRadius(((Double)_measRad.getValue()).floatValue());
	    _data_sensor.setController((String)_controllerStrategy.getSelectedItem());
		_data_sensor.setBatteryLevel(((Double)_battery.getValue()).doubleValue());
		/*Vector probes = new Vector();
	    for(Enumeration e = _model.elements() ; e.hasMoreElements() ;) {
		probes.add(e.nextElement());
	    }
	    _data_sensor.setProbes(probes);*/
	    double[] consumption = new double[Station.NBSTATES-1];
	    consumption[Station.WAITING] = ((Double)_waiting.getValue()).doubleValue();
	    consumption[Station.LISTENING] = ((Double)_listening.getValue()).doubleValue();
	    consumption[Station.SPEAKING] = ((Double)_speaking.getValue()).doubleValue();
	    consumption[Station.SLEEPING] = ((Double)_sleeping.getValue()).doubleValue();
	    _data_sensor.setConsumption(consumption);
	}

	public void actionPerformed(ActionEvent e)
	{
	    /*    Component source = (Component)e.getSource();
	    if(source == _add)
		{
		    _model.addElement((String)_probes.getSelectedItem());
		}
	    else if(source == _remove)
		{
		    int index = _list.getSelectedIndex();
		    if(index != -1) _model.remove(index);
		    }*/
	}
	
    }

    private class EmissionPanel extends JPanel {
	
	private EmissionPanel()
	{
	    setLayout(new BorderLayout());
	    
	    JPanel events = new JPanel();	    
	    events.setLayout(new GridLayout(3,2,4,4));
	    events.setBorder(new EmptyBorder(4,4,4,4));

	    // TODO

	    add("North", events);	    
	}
	public void apply()
	{
	}

    }

}
